package com.zt.bigdata.practise.javastrategy.chapter5;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 */
public class Chapter5 {
    private static final Logger logger = LoggerFactory.getLogger(Chapter5.class);
    private static Map<Long, BigInteger> cache = new HashMap<>();

    public static void main(String[] args) {
        //5.1 java.util.Objects类
        List<String> strings = Arrays.asList(
                "this", null, "is", "a", null, "list", "of", "strings", null);
        List<String> nonNullStrings = strings.stream().filter(Objects::nonNull)
                .collect(Collectors.toList());

        System.out.println(Objects.deepEquals(strings, nonNullStrings));//false

        //5.2 lambda表达式与效果等同于final的变量
        int total = 0;
        //Arrays.asList(3, 1, 4, 1, 5, 9).stream().forEach(n -> total += n);  total 是final类型
        //5.3 随机数流
        Random r = new Random();
        r.ints(5).sorted().forEach(System.out::println);
        r.doubles(5, 0, 0.5).sorted().forEach(System.out::println);
        List<Long> longs = r.longs(5).boxed().collect(Collectors.toList());
        System.out.println(longs);
        List<Integer> listOfInts = r.ints(5, 10, 20)
                .collect(LinkedList::new, LinkedList::add, LinkedList::addAll);
        System.out.println(listOfInts);
        //5.4 Map接口的默认方法
        fib(5);
        System.out.println("compute 之前" + cache.get(3L));
        cache.compute(3L, (key, value) -> value.add(BigInteger.TEN));
        System.out.println("compute 之后" + cache.get(3L));
        cache.computeIfAbsent(10L, key -> BigInteger.TEN);
        System.out.println(cache.get(10L));
        cache.forEach((k, v) -> System.out.println(k + " " + v));

        //5.8 闭包复合
        Function<Integer, Integer> add2 = x -> x + 2;
        Function<Integer, Integer> mult3 = x -> x * 3;

        Function<Integer, Integer> mult3add2 = add2.compose(mult3); //调用 add2 之前调用 mult3
        Function<Integer, Integer> add2mult3 = add2.andThen(mult3); //调用 add2 之后调用 mult3

        System.out.println("mult3add2(1): " + mult3add2.apply(1));
        System.out.println("add2mult3(1): " + add2mult3.apply(1));
    }

    public static BigInteger fib(long i) {
        if (i == 0) {
            return BigInteger.ZERO;
        }
        if (i == 1) {
            return BigInteger.ONE;
        }
        return cache.computeIfAbsent(i, n -> fib(n - 2).add(fib(n - 1)));
        //如果键的值在缓存中存在，返回对应的值，否则计算新的值并保存
    }


}
